package ks.managers.user;

import java.util.Date;

/**
 * Represents a user of the KS system.
 * 
 * @author George Heineman
 * @author Christopher Page
 */
public class User {

	/** The user's username.
	 * 
	 * @see #User(String, String)
	 * @see #equals(Object)
	 * @see #toString()
	 */
	public final String name;
	
	/** The md5 sum of the user's password.
	 * 
	 * @see #User(String, String)
	 * @see #validate(String)
	 */
	String encryptedPassword;
	
	/**
	 * The name of the user's chosen icon.
	 * 
	 * @see #setIconName(String)
	 * @see #getIconName()
	 */
	String iconName;
	
	/**
	 * The user's rating.
	 * 
	 * @see #setRating(int)
	 * @see #getRating()
	 * @see #toString()
	 */
	int rating;

	/**
	 * The number of games won by the user.
	 * 
	 * @see #setGamesWon(int)
	 * @see #getGamesPlayed()
	 * @see #getGamesWon()
	 */
	int gamesWon;
	
	/**
	 * The number of games lost by the user.
	 * 
	 * @see #setGamesLost(int)
	 * @see #getGamesPlayed()
	 * @see #getGamesLost()
	 */
	int gamesLost;
	
	/**
	 * Last login date of the user.
	 * 
	 * @see #setLastLogin(long)
	 * @see #setLastLogin(Date)
	 * @see #getLastLogin()
	 */
	long lastLogin;
	
	/**
	 * Whether or not the user is an admin.
	 * 
	 * @see #setAdmin(boolean)
	 * @see #isAdmin()
	 */
	boolean isAdmin;
	
	boolean isBlocked;
	
	
	/**
	 * Construct a user from a given name and encrypted password.
	 * 
	 * @param name              The username of the user.
	 * @param encryptedPassword The md5 sum of the user's password.
	 */
	public User (String name, String encryptedPassword) {
		this.name = name;
		this.encryptedPassword = encryptedPassword;
		this.gamesLost = 0;
		this.gamesWon = 0;
		this.iconName = "";
		this.isAdmin = false;
		this.isBlocked = false;
		this.lastLogin = 0;
		this.rating = 0;
	}
	
	/**
	 * Retrieves the User's username.
	 * 
	 * @return The name of the User.
	 */
	public String getName() { return this.name; }
	
	/**
	 * Retrieves the User's encrypted password.
	 * 
	 * @return The encrypted password of the User.
	 */
	public String getEncPwd() { return this.encryptedPassword; }
	
	/**
	 * Changes the encryptedPassword
	 * 
	 * @param encPwd The new encrypted password
	 */
	public void setEncPwd(String encPwd) { this.encryptedPassword = encPwd; }
	
	/**
	 * Update admin status of the user.
	 * 
	 * @param b A boolean representing whether or not the user is an admin.
	 */
	public void setAdmin(boolean b) { isAdmin = b; }
	
	/**
	 * Update blocked status of the user
	 * 
	 * @param b
	 */
	public void setBlocked(boolean b) { isBlocked = b; }
	
	/**
	 * Validate user password.
	 * 
	 * @param encrypted The md5 sum of the user's password which is to be 
	 *                  checked.
	 * @return A boolean value representing whether or not the password is 
	 *         valid.
	 */
	public boolean validate (String encrypted) {
		return encryptedPassword.equals(encrypted);
	}
	
	/**
	 * Determine admin status of user.
	 * 
	 * @return A boolean representing whether or not the user is an admin.
	 */
	public boolean isAdmin() { return isAdmin; }
	
	/**
	 * Determine the blocked status of user.
	 * 
	 * @return A boolean representing whether or not the user is blocked.
	 */
	public boolean isBlocked() { return isBlocked; }
	
	/**
	 * Update icon for user.
	 * 
	 * @param name The name of the icon.
	 */
	public void setIconName(String name) { iconName = name; }
	
	/**
	 * Determine icon for user.
	 * 
	 * @return The name of the player's icon.
	 */
	public String getIconName() { return iconName; }

	/**
	 * Set the number of games the user has won.
	 * 
	 * @param w The number of games the user has won.
	 */
	public void setGamesWon(int w) { gamesWon = w; }
	
	/**
	 * Set the number of games the user has lost.
	 * 
	 * @param l The number of games the user has lost.
	 */
	public void setGamesLost(int l) { gamesLost = l; }
	
	/**
	 * Determine total number of games the user has played.
	 * 
	 * @return An integer representing the number of games the user has played.
	 */
	public int getGamesPlayed() { return gamesWon + gamesLost; }
	
	/**
	 * Determine the number of games the user has won.
	 * 
	 * @return An integer representing the number of games the user has won.
	 */
	public int getGamesWon() { return gamesWon; }
	
	/**
	 * Determine the number of games the user has lost.
	 * 
	 * @return An integer representing the number of games the user has lost.
	 */
	public int getGamesLost() { return gamesLost; }
	
	/**
	 * Determine last login date.
	 * 
	 * @return A long representing the last login date of the user.
	 */
	public long getLastLogin() { return lastLogin; }
	
	/**
	 * Update login time.
	 * 
	 * @param time A long representing the last login time of the user.
	 */
	public void setLastLogin(long time) { lastLogin = time; }
	
	/**
	 * Update login time.
	 * 
	 * @param d A Date representing the last login time of the user.
	 */
	public void setLastLogin(Date d) { lastLogin = d.getTime(); }

	/**
	 * Update player rating.
	 * 
	 * @param newRating The new rating of the user.
	 */
	public void setRating (int newRating) { rating = newRating; }
	
	/**
	 * Return player rating.
	 * 
	 * @return The rating of the user.
	 */
	public int getRating() { return rating; }
	
	/**
	 * Two users are equal if their names are the same.
	 * 
	 * @param o The user to compare to this one.
	 * @return Whether or not the other user is the same as this one.
	 */
	public boolean equals (Object o) {
		// if object null: false
		if (o == null) { return false; }
		
		// if object is instance of User class
		if (o instanceof User) {
			User other = (User) o;
			return (other.name.equals (name)); //return whether usernames match
		}
		
		// object is not instance of User class: false
		return false;
	}
	
	/**
	 * toString() method. Useful for both GUIs and debugging.
	 * 
	 * @return A string containing the username and the user's rating.
	 * */
	public String toString() {
		return name + " (" + rating + ")";
	}
}
